package com.gitee.ywj1352.proxy.dynamic.custom;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * @author wenjie.yang on 3/25/2019.
 */
public class YWJProxy {

  public static final String ln = "\r\n";

  public static Object newProxyInstance(YWJClassLoader classLoader,Class<?>[] interfaces,YWJInvocationHandler h){

    //1.动态生成源代码.java 文件
    generateSrc(interfaces);
    //2.把java 文件输出到磁盘
    try {
      //3.把生成的java文件 编译成class文件
      JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
      StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
      Iterable iterable = manager.getJavaFileObjects(new File("c:/"));

      JavaCompiler.CompilationTask task = compiler.getTask(null , manager, null,null,null,iterable);
      task.call();
      manager.close();

      //4.把编译生成的.class文件加载到jvm中来
      Class<?> proxyClass = classLoader.findClass("$proxy0.class");
      Constructor<?> constructor = proxyClass.getConstructor(YWJInvocationHandler.class);

      //5.返回字节码重组以后的新的代理对象
      return  constructor.newInstance(h);
    }catch (Exception e){
      e.printStackTrace();
    }


    return null;

  }

  private static String generateSrc(Class<?>[] interfaces){
    StringBuffer sb= new StringBuffer();
    sb.append("package com.gitee.ywj1352.proxy.dynamic.custom;"+ln);
    sb.append("public class $Proxy0 implements "+ interfaces[0].getName()+"{"+ ln);
    sb.append("YWJInvocationHandler h;"+ln);
    sb.append("public $Proxy0(YWJInvocationHandler h) {"+ln);
    sb.append("this.h = h;"+ln);
    sb.append("}"+ln);

    for (Method m :interfaces[0].getMethods()){
      sb.append("public " + m.getReturnType().getName() + " " + m.getName() +"() {" +ln);
        sb.append("try {");
        sb.append(""+ interfaces[0].getName()+".class.getMethod(");
        sb.append("} catch(Exception e){");
        sb.append("e.printStackTrace();");
        sb.append("}");

      sb.append("}");
    }
    sb.append("}" + ln);
    return null;
  }

}
